package org.kca.yarmour.data;

import java.awt.Color;
import java.io.IOException;

import org.kca.yarmour.YAException;
import org.kca.yarmour.yadata.EntryType;
import org.kca.yarmour.yadata.TableType;
import org.kca.graphics.GameCore;
import org.kca.graphics.Texture;

public class GlobalData
{
    public static final int MAP_WIDTH = 2048;
    public static final int MAP_HEIGHT = 1152;
    public static final int SQUARE_SIZE = 32;
    public static final int MAP_ROWS = 36;
    public static final int MAP_COLS = 64;
    public static final String ART_FOLDER = "art/";
    public static final String WEATHER_FOLDER = ART_FOLDER + "Weather/";
    public static final String TERRAIN_FOLDER = ART_FOLDER + "Terrain/";
    public static final String FACTION_FOLDER = ART_FOLDER + "Factions/";
    public static final String BUTTONS_FOLDER = ART_FOLDER + "Buttons/";
    public static final String CARGO_FOLDER = ART_FOLDER + "Cargo/";
    public static final String MAP_FILENAME = ART_FOLDER + "worldmap.jpg";
    public static final String HIGH_TIDE_FILENAME = WEATHER_FOLDER + "HighTide.png";
    public static final String LOW_TIDE_FILENAME = WEATHER_FOLDER + "LowTide.png";
    public static final String PSI_FILENAME = WEATHER_FOLDER + "PSI.png";
    public static final String ASEAN_FILENAME = ART_FOLDER + "Asean.png";
    public static final String CARGO_FILENAME = ART_FOLDER + "Cargo.png";
    public static final String TOWN_ICON_FILENAME = TERRAIN_FOLDER + "Town.png";
    public static final String LAAGER_ICON_FILENAME = BUTTONS_FOLDER + "EnterTown.png";
    public static final String SEARCH_ICON_FILENAME = BUTTONS_FOLDER + "Search.png";
    public static final String HIDE_ICON_FILENAME = BUTTONS_FOLDER + "Hide.png";
    public static final String QUEST_ICON_FILENAME = BUTTONS_FOLDER + "Quest.png";
    public static final String SUPERMARKET_ICON_FILENAME = BUTTONS_FOLDER + "Supermarket.png";
    public static final String WORKSHOP_ICON_FILENAME = BUTTONS_FOLDER + "Workshop.png";
    public static final String KOPITIAM_ICON_FILENAME = BUTTONS_FOLDER + "Kopitiam.png";
    public static final String FACBRANCH_ICON_FILENAME = BUTTONS_FOLDER + "FacBranch.png";
    public static final String RIGHT_ARROW_FILENAME = BUTTONS_FOLDER + "RightArrow.png";
    public static final String LEFT_ARROW_FILENAME = BUTTONS_FOLDER + "LeftArrow.png";
    public static final String MAXIMUM_ARROW_FILENAME = BUTTONS_FOLDER + "DoubleUpArrow.png";
    
    public static final int DIR_UP = 0;
    public static final int DIR_DOWN = 1;
    public static final int DIR_LEFT = 2;
    public static final int DIR_RIGHT = 3;
    
    /* Time constants */
    public static final int GAME_START_YEAR = 2160;
    public static final int GAME_START_MONTH = 0;
    public static final int GAME_START_DAY = 1;
    public static final int GAME_START_HOUR = 7;
    public static final int GAME_START_MIN = 0;
    
    /* Event constants */
    public static final int WEATHER_CHANGE_HOURS = 12;
    public static final int EVENT_WEATHER_CHANGE = 1;
    
    /** The tide is high if the value is greater than or equal to this threshold */
    public static final int HIGH_TIDE_THRESHOLD = 50;
    
    /* Table names */
    public static final String TERRAIN_TRAVEL_TABLE = "Terrain Travel Times";
    
    /* Colors */
    
    /* Game related constants */
    public static final int QUEST_LIST_MAX_SIZE = 25;
    
    public enum TerrainType
    {
        DJUNGLE ("DJungle"),
        LJUNGLE ("LJungle"),
        DURBAN ("DUrban"),
        LURBAN ("LUrban"),
        WATER ("Water"),
        FLATLAND ("Flatland"),
        EXPRESSWAY ("Expressway"),
        SWAMP ("Swamp"),
        BRIDGE ("Bridge"),
        CLOSED ("Closed");
        
        private String name;
        private Texture texture;
        private int travelTime;
        
        private TerrainType(String n)
        {
            this.name = n;
            try
            {
                texture = GameCore.getTextureLoader().getTexture(getTextureFilename());
            }
            catch (IOException e)
            {
                throw new YAException("Failed to find " + getTextureFilename());
            }
        }
        
        public String getName()
        {
            return name;
        }
        
        public Texture getImage()
        {
            return texture;
        }
        
        /**
         * Gets the travel time in hours to pass this terrain, or -1 if the
         * terrain is impassable
         * @return the travel time
         */
        public int getTravelTime()
        {
            return travelTime;
        }
        
        private String getTextureFilename()
        {
            return TERRAIN_FOLDER + name + ".png";
        }
        
        public static TerrainType getTerrain(String terrain)
        {
            for (TerrainType type : TerrainType.values())
            {
                if (type.getName().equalsIgnoreCase(terrain))
                {
                    return type;
                }
            }
            return null;
        }
        
        /**
         * Initializes the travel times for different terrain
         * @param table terrain travel time table (TTTT)
         */
        static void initializeTerrain(TableType table)
        {
            if (table.getName().equals(TERRAIN_TRAVEL_TABLE))
            {
                for (EntryType en : table.getEntry())
                {
                    TerrainType type = getTerrain(en.getKey());
                    if (type != null)
                    {
                        type.travelTime = Integer.parseInt(en.getValue());
                    }
                }
            }
        }
    }
    
    public enum WeatherType
    {
        CLEAR ("Clear"),
        CLOUDY ("Cloudy"),
        RAINY ("Rainy"),
        HAIL ("Hail"),
        OVERCAST ("Overcast"),
        CAT1 ("Cat1");
        
        private String name;
        private Texture texture;
        
        private WeatherType(String n)
        {
            this.name = n;
            try
            {
                texture = GameCore.getTextureLoader().getTexture(getTextureFilename());
            }
            catch (IOException e)
            {
                throw new YAException("Failed to find " + getTextureFilename());
            }
        }
        
        public String getName()
        {
            return name;
        }
        
        public Texture getImage()
        {
            return texture;
        }
        
        public String getTextureFilename()
        {
            return WEATHER_FOLDER + name + ".png";
        }
        
        public static WeatherType getWeather(String weather)
        {
            for (WeatherType type : WeatherType.values())
            {
                if (type.getName().equalsIgnoreCase(weather))
                {
                    return type;
                }
            }
            return null;
        }
    }
    
    public enum FactionType
    {
        HUAT("huat", new Color(0.125f, 0.7f, 0.3f)),
        NATIONAL("National", new Color(1, 0.5f, 0.15f)),
        PAS("PAS", new Color(0.25f, 0.3f, 0.8f)),
        SINGCORP("SingCorp", Color.red),
        NONE("None", new Color(0, 0, 0, 0));
        
        private String name;
        private Texture texture;
        private Color color;
        
        FactionType(String name, Color col)
        {
            this.name = name;
            this.color = col;
            try
            {
                texture = GameCore.getTextureLoader().getTexture(getTextureFilename());
            }
            catch (IOException e)
            {
                throw new YAException("Failed to find " + getTextureFilename());
            }
        }

        /**
         * Gets the faction name
         * @return the name
         */
        public String getName()
        {
            return name;
        }

        /**
         * Gets the faction icon
         * @return the icon texture
         */
        public Texture getImage()
        {
            return texture;
        }
        
        /**
         * Gets the faction color
         * @return the faction color
         */
        public Color getColor()
        {
            return color;
        }
        
        /**
         * Gets the number of different factions
         * @return the number of factions
         */
        public static int getNumFactions()
        {
            return values().length;
        }
        
        public String getTextureFilename()
        {
            return FACTION_FOLDER + name + ".png";
        }
        
        public static FactionType getFaction(String faction)
        {
            for (FactionType type : FactionType.values())
            {
                if (type.getName().equalsIgnoreCase(faction))
                {
                    return type;
                }
            }
            return null;
        }
    }
    
    public enum CargoType
    {
        FUEL ("Fuel"),
        WATER ("Water"),
        AMMO ("Ammo"),
        MEDICINE ("Medicine"),
        TOOLS ("Tools"),
        RIFLES ("Rifles"),
        CURRY ("Curry");
        
        private String name;
        private Texture texture;
        
        CargoType(String name)
        {
            this.name = name;
            try
            {
                texture = GameCore.getTextureLoader().getTexture(getTextureFilename());
            }
            catch (IOException e)
            {
                throw new YAException("Failed to find " + getTextureFilename());
            }
        }

        /**
         * Gets the cargo name
         * @return the name
         */
        public String getName()
        {
            return name;
        }

        /**
         * Gets the cargo icon
         * @return the icon texture
         */
        public Texture getImage()
        {
            return texture;
        }
        
        /**
         * Gets the number of different types of cargo
         * @return the number of cargo types
         */
        public static int getNumTypes()
        {
            return values().length;
        }
        
        /**
         * Gets the type of cargo by index
         * @param index the index of the cargo type
         * @return the cargo type
         */
        public static CargoType getCargoType(int index)
        {
            if (index >= 0 && index < CargoType.values().length)
            {
                return CargoType.values()[index];
            }
            else return null;
        }
        
        /**
         * Gets the name of cargo by index
         * @param index the index of the cargo type
         * @return the name of that cargo type
         */
        public static String getCargoName(int index)
        {
            return getCargoType(index).getName();
        }
        
        /**
         * Gets the texture filename associated with this cargo type
         * @return the texture filename
         */
        public String getTextureFilename()
        {
            return CARGO_FOLDER + name + ".png";
        }
        
        public static CargoType getCargo(String cargo)
        {
            for (CargoType type : CargoType.values())
            {
                if (type.getName().equalsIgnoreCase(cargo))
                {
                    return type;
                }
            }
            return null;
        }
        
    }
    
    public enum InvItemType
    {
        VEHICLE_MOD ("Mod"),
        TROOPER_WEAPON ("Weapon"),
        QUEST_ITEM ("Quest"),
        GENERAL_ITEM ("General");
        
        private String name;
        
        InvItemType(String name)
        {
            this.name = name;
        }

        /**
         * Gets the cargo name
         * @return the name
         */
        public String getName()
        {
            return name;
        }
        
        public static InvItemType getItemType(String itemType)
        {
            for (InvItemType type : InvItemType.values())
            {
                if (type.getName().equalsIgnoreCase(itemType))
                {
                    return type;
                }
            }
            return null;
        }
    }
    
    public enum QuestType
    {
        SINGLE ("Single"),
        SINGLE_NR ("Non-repeatable"),
        DAILY ("Daily"),
        RESPAWNING ("Respawning");
        
        private String name;
        
        QuestType(String name)
        {
            this.name = name;
        }

        /**
         * Gets the cargo name
         * @return the name
         */
        public String getName()
        {
            return name;
        }
        
        public static QuestType getQuestType(String questType)
        {
            for (QuestType type : QuestType.values())
            {
                if (type.getName().equalsIgnoreCase(questType))
                {
                    return type;
                }
            }
            return null;
        }
    }
}
